home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / jcool01.zip / LIST.C < prev    next >
C/C++ Source or Header  |  1992-08-19  |  12KB  |  357 lines

  1. //
  2. // Copyright (C) 1991 Texas Instruments Incorporated.
  3. //
  4. // Permission is granted to any individual or institution to use, copy, modify,
  5. // and distribute this software, provided that this complete copyright and
  6. // permission notice is maintained, intact, in all copies and supporting
  7. // documentation.
  8. //
  9. // Texas Instruments Incorporated provides this software "as is" without
  10. // express or implied warranty.
  11. //
  12.  
  13. #include <cool/List.h>
  14.  
  15. // compare_s -- Function used by == test
  16. template <class Type>
  17. Boolean (*CoolList<Type>::compare_s)(const Type&, const Type&) = &CoolList_is_data_equal;
  18.  
  19. // CoolList_Node<Type>() -- A CoolList Node constructor to create a node from head and
  20. //                      tail specified
  21. // Input:               A Type reference and CoolList reference.
  22. // Output:              None.
  23.  
  24. template <class Type> 
  25. CoolList_Node<Type>::CoolList_Node(const Type& head, CoolList_Node<Type>* tail) {
  26.   this->ref_count = 1;
  27.   this->next = tail;
  28.   this->data = (Type&) head;
  29. }
  30.  
  31. template <class Type> 
  32. CoolList_Node<Type>::~CoolList_Node() {    // data is deleled when object
  33. }                        // is stored.
  34.  
  35. // get_data()  -- Gets data of node.
  36. // Input:         None.
  37. // Output:        A void* pointer.
  38.  
  39. template <class Type> 
  40. const void* CoolList_Node<Type>::get_data() {
  41.   return &this->data;
  42. }
  43.  
  44.  
  45. // set_data()  -- Sets data of node to specified value.
  46. // Input:         A void* pointer.
  47. // Output:        None.
  48.  
  49. template <class Type> 
  50. void CoolList_Node<Type>::set_data(const void* value) {
  51.   this->data = *(Type*)value;
  52. }
  53.  
  54.  
  55.  
  56. // CoolList<Type>() -- a CoolList constructor to create a CoolList instance with no
  57. //                 elements.  The node pointer is initialized to NULL.
  58. // Input:          None.
  59. // Output:         None.
  60.  
  61. template <class Type> 
  62. CoolList<Type>::CoolList() {
  63.   this->reset();
  64.   this->node_ptr = NULL;
  65. }
  66.  
  67.  
  68. // CoolList<Type>() -- A CoolList constructor to create a CoolList with one element
  69. // Input:          A Type reference.
  70. // Output:         None.
  71.  
  72. template <class Type> 
  73. CoolList<Type>::CoolList(const Type& head) {
  74.   this->reset();
  75.   this->node_ptr = new CoolList_Node<Type>(head, (CoolList_Node<Type>*)NULL);
  76. }
  77.  
  78.  
  79. // CoolList<Type>() -- A CoolList constructor to create a CoolList with the specified
  80. //                 head element and list tail.
  81. // Input:          A Type reference and CoolList reference.
  82. // Output:         None.
  83.  
  84. template <class Type> 
  85. CoolList<Type>::CoolList(const Type& head, CoolList<Type>& tail) {
  86.   this->reset();
  87.   this->node_ptr = new CoolList_Node<Type>(head, (CoolList_Node<Type>*)tail.node_ptr);
  88.   this->reference(tail.node_ptr);
  89. }
  90.  
  91.  
  92. // CoolList<Type>() -- A CoolList constructor to create a CoolList from the specified list.
  93. // Input:          A CoolList reference.
  94. // Output:         None.
  95.  
  96. template <class Type> 
  97. CoolList<Type>::CoolList(CoolList<Type>& tail) {
  98.   this->reset();
  99.   this->node_ptr = (CoolList_Node<Type>*)tail.node_ptr;
  100.   this->reference(this->node_ptr);
  101. }
  102.  
  103. // CoolList<Type>() -- A CoolList constructor to initialize a CoolList with "n" elements.
  104. // Input:          The number of elements, and "n" data Type elements
  105. // Output:         None.
  106. // Note: Arguments in ... can only be pointers, primitive types like int, double,
  107. //       and NOT OBJECTS, passed by reference or value, like vectors, matrices;
  108. //       because constructors must be known and called at compile time!!!
  109. //       Cannot have char in ..., because char is 1 instead of 4 bytes, and 
  110. //       va_arg expects sizeof(Type) a multiple of 4 bytes.
  111.  
  112. template <class Type> 
  113. CoolList<Type>::CoolList(int n, Type head, ...) {
  114. #if ERROR_CHECKING
  115.   if (((sizeof(Type) % 4) != 0) ||        // Cause alignment problems
  116.       (sizeof(Type) > 8))            // User defined classes?
  117.     this->va_arg_error(#Type, sizeof(Type));    // So, cannot use this constructor
  118. #endif
  119.   this->reset();
  120.   if (n > 0) {
  121.     va_list argp;
  122.     va_start(argp, head);
  123.     // add head node
  124.     this->node_ptr = new CoolList_Node<Type>(head, (CoolList_Node<Type>*)NULL);
  125.     // add remaining nodes
  126.     CoolBase_List_Node* prev_np = this->node_ptr;
  127.     CoolBase_List_Node* next_np;
  128.     for (int i = 1; i < n; i++) {
  129.       Type temp = va_arg(argp, Type);
  130.       next_np = new CoolList_Node<Type>(temp, (CoolList_Node<Type>*)NULL);
  131.       prev_np->next_node() = next_np;
  132.       prev_np = next_np;
  133.     }
  134.     va_end(argp);
  135.   }
  136.   else  this->node_ptr = (CoolList_Node<Type>*)0;
  137. }
  138.  
  139. // ~CoolList<Type>() -- the CoolList destructor will decrement reference counts
  140. //                  starting at head node and free up memory allocated by
  141. //                  these nodes if they are no longer referenced.
  142. // Input:           None.
  143. // Output:          None.
  144.  
  145. template <class Type> 
  146. CoolList<Type>::~CoolList() {
  147.   this->dereference(this->node_ptr);
  148. }
  149.  
  150. // operator[]() -- Returns the nth node of THIS list.
  151. // Input:          A positive integer index.
  152. // Output:         A Type reference of data in the nth node of THIS.
  153.  
  154. template <class Type> 
  155. Type& CoolList<Type>::operator[] (int n) {
  156.   CoolList_Node<Type>* np = (CoolList_Node<Type>*)CoolBase_List::operator[](n);
  157. #if ERROR_CHECKING
  158.   if (np == NULL)
  159.     this->bracket_error (#Type, n);
  160. #endif
  161.   return np->data;
  162. }
  163.  
  164. // put() -- Replaces the data slot of the nth node of this list and if
  165. //          successful, returns the  new data item. With no arguments,
  166. //          replaces the data at the first node.
  167. // Input:   A Type reference and a positive integer index.
  168. // Output:  TRUE if nth node exists, FALSE otherwise.
  169.  
  170. template <class Type> 
  171. Boolean CoolList<Type>::put(const Type& x, int n) {
  172.   CoolList_Node<Type>* np = (CoolList_Node<Type>*)CoolBase_List::operator[](n);
  173.   if (np != NULL) {
  174.     np->data = x;
  175.     return TRUE;
  176.   }
  177.   else return FALSE;
  178. }
  179.  
  180. template <class Type> 
  181. Boolean CoolList<Type>::do_find(CoolBase_List_Node* np, const void* x, CoolBase_List_Node*& cp, CoolBase_List_Node*& pp) const {
  182.   CoolBase_List_Node* prev_np = NULL;
  183.   for (; np != NULL; 
  184.        prev_np = np, np = np->next_node())
  185.     if ((*compare_s)(((const CoolList_Node<Type>*) np)->data, *(const Type*)x)) {
  186.       cp = np;                    // found x
  187.       pp = prev_np;
  188.       return TRUE;
  189.     }
  190.   cp = NULL;
  191.   pp = NULL;
  192.   return FALSE;
  193. }
  194.  
  195. // push() -- Prepends the specified data item to the front of this list
  196. // Input:    A Type reference to the data item to be prepended.
  197. // Output:   TRUE.
  198.  
  199. template <class Type> 
  200. Boolean CoolList<Type>::push(const Type& x) {
  201.   CoolBase_List_Node* anode = new CoolList_Node<Type>(x, (CoolList_Node<Type>*) this->node_ptr);
  202.   if (!anode)
  203.     return FALSE;
  204.   this->curpos = anode;
  205.   this->node_ptr = anode;
  206.   this->prevpos = NULL;
  207.   return TRUE;
  208. }
  209.  
  210.  
  211. // pop() -- Removes and returns head element of THIS list.
  212. // Input:   None.
  213. // Output:  A copy of the head data element of THIS list.
  214.  
  215. template <class Type> 
  216. Type CoolList<Type>::pop() {
  217.   CoolList_Node<Type>* head = (CoolList_Node<Type>*)CoolBase_List::pop();
  218. #if ERROR_CHECKING
  219.   if (head == NULL)
  220.     this->pop_error (#Type);
  221. #endif
  222.   Type head_data = head->data;
  223.   this->dereference(head);
  224.   return head_data;
  225. }
  226.  
  227.  
  228. // pop(Type& result) -- Removes head node and returns data
  229. // Input:   Reference to place to copy the result.
  230. // Output:  returns TRUE when the list is empty
  231.  
  232. template <class Type> 
  233. Boolean CoolList<Type>::pop(Type& result) {
  234.   CoolList_Node<Type>* head = (CoolList_Node<Type>*)CoolBase_List::pop();
  235. #if ERROR_CHECKING
  236.   if (head == NULL) 
  237.     this->pop_error (#Type);
  238. #endif
  239.   result = head->data;
  240.   this->dereference(head);
  241.   return TRUE;
  242. }
  243.  
  244.  
  245. // remove() -- Removes item at current position.
  246. // Input:      None.
  247. // Output:     The item removed.
  248.  
  249. template <class Type> 
  250. Type CoolList<Type>::remove() {
  251.   CoolList_Node<Type>* np = (CoolList_Node<Type>*)CoolBase_List::remove();
  252. #if ERROR_CHECKING
  253.   if (np == NULL)
  254.     this->remove_error (#Type);
  255. #endif
  256.   Type removed_data = np->data;            // temp deleted on exit
  257.   this->dereference(np);            // remove node
  258.   return removed_data;                // copy of temp returned
  259. }
  260.  
  261. // CoolList<Type>() -- A CoolList constructor used internally by CoolList member functions
  262. //                 to initialize a CoolList object with an object with a pointer
  263. //                 to a node structure
  264. // Input:          The node pointer.
  265. // Output:         None.
  266.  
  267. template <class Type> 
  268. CoolList<Type>::CoolList(CoolList_Node<Type>* head_node) {
  269.   this->node_ptr = head_node;
  270.   this->reference(head_node);
  271. }
  272.  
  273. // new_list() -- Returns a new list with head node initialized to node.
  274. // Input:        The node pointer.
  275. // Output:       A pointer to the new list.
  276.  
  277. template <class Type> 
  278. CoolBase_List* CoolList<Type>::new_list(CoolBase_List_Node* head_node) {
  279.   CoolList<Type>* l = new CoolList<Type>((CoolList_Node<Type>*)head_node);
  280.   return (CoolList*) l;
  281. }
  282.  
  283.  
  284. // insert_before_node() -- Insert a new node before the specified node.
  285. // Input:                  A Type reference and a Node pointer.
  286. // Output:                 A pointer to the new node.
  287.  
  288. template <class Type> 
  289. CoolBase_List_Node* CoolList<Type>::insert_before_node(const void* value, CoolBase_List_Node* next_np) {
  290.   CoolBase_List_Node* anode = new CoolList_Node<Type>(*(Type*)value, 
  291.                                               (CoolList_Node<Type>*)next_np);
  292.   return anode;
  293. }
  294.  
  295.  
  296. // insert_after_node() -- Inserts a new node after the specified node.
  297. // Input:                 A Type reference and a Node pointer.
  298. // Output:                A pointer to the new node.
  299.  
  300. template <class Type> 
  301. CoolBase_List_Node* CoolList<Type>::insert_after_node(const void* value, CoolBase_List_Node* prev_np) const {
  302.   CoolBase_List_Node* anode = new CoolList_Node<Type>(*(Type*)value, (CoolList_Node<Type>*)NULL);
  303.   // note that if prev_np is NULL,
  304.   // then we just return a new node with no reference to it.
  305.   if (prev_np != NULL) {
  306.      anode->next_node() = prev_np->next_node();
  307.      prev_np->next_node() = anode;
  308.    }
  309.   return anode;
  310. }
  311.  
  312. // is_data_equal() -- A private friend function used internnaly returning TRUE
  313. //                    if a == b.  The default value of  the CoolList Compare slot
  314. //                    is set to the address of this function. This must be
  315. //                    done to get the address of operator==.
  316. // Input:             The two void* pointers to be compared.
  317. // Output:            TRUE if items are equal, FALSE otherwise. 
  318.  
  319. template<class Type>
  320. Boolean CoolList_is_data_equal (const Type& a, const Type& b) {
  321.     return (a == b);
  322. }
  323.  
  324. // set_compare() -- Sets the Compare function.
  325. // Input:           A compare function pointer.
  326. // Output:          None.
  327.  
  328. template <class Type> 
  329. void CoolList<Type>::set_compare(Boolean (*cf)(const Type&, const Type&)) {
  330.   if (cf == NULL)                // If no value supplied
  331.     this->compare_s = &CoolList_is_data_equal; // Use default compare
  332.   else
  333.     this->compare_s = cf;                // Else set to user function
  334. }
  335.  
  336.  
  337. // compare_data() -- Compares data using default compare function of this list
  338. // Input:            Two void* pointers which will be type cast.
  339. // Output:           None.
  340.  
  341. template <class Type> 
  342. Boolean CoolList<Type>::compare_data(const void* a, const void* b) const {
  343.   return (*compare_s)(*(const Type*)a, *(const Type*)b);
  344. }
  345.  
  346.  
  347. // output_data()  -- Outputs node data from specified stream and is called
  348. //                   by operator<<.
  349. // Input:            An output stream reference and node pointer.
  350. // Output:           A void* pointer of data.
  351.  
  352. template <class Type> 
  353. void CoolList<Type>::output_data(ostream& os, const CoolBase_List_Node* np) const {
  354.   os << ((const CoolList_Node<Type>*)np)->data;
  355. }
  356.  
  357.